/**
 * Created by hlh on 2015/7/20.
 */
import 'babel-core/polyfill';
var $ = document.querySelector.bind(document);
var $$ = document.querySelectorAll.bind(document);
var gcs = window.getComputedStyle.bind(window);

/*
 var domQuery = (function () {
 var aDOMFunc = [
 Element.prototype.removeAttribute,
 Element.prototype.setAttribute,
 CSSStyleDeclaration.prototype.removeProperty,
 CSSStyleDeclaration.prototype.setProperty
 ];

 function setSomething(bStyle, sProp, sVal) {
 var bSet = Boolean(sVal), fAction = aDOMFunc[bSet | bStyle << 1],
 aArgs = Array.prototype.slice.call(arguments, 1, bSet ? 3 : 2),
 aNodeList = bStyle ? this.cssNodes : this.nodes;

 if (bSet && bStyle) {
 aArgs.push('');
 }
 for (
 var nItem = 0, nLen = this.nodes.length;
 nItem < nLen;
 fAction.apply(aNodeList[nItem++], aArgs)
 );
 return this;
 }

 function setStyles(sProp, sVal) {
 return setSomething.call(this, true, sProp, sVal);
 }

 function setAttribs(sProp, sVal) {
 return setSomething.call(this, false, sProp, sVal);
 }

 function getSelectors() {
 return this.selectors;
 };
 function getNodes() {
 return this.nodes;
 };
 function findNext() {
 return domQuery(this.selectors.nextElementSibling);
 };
 function findMom() {
 return domQuery(this.selectors.parentElement);
 };
 return (function (sSelectors) {
 var oQuery = new Function('return arguments.callee.follow.apply(arguments.callee, arguments);');
 oQuery.selectors = sSelectors;
 var isElement = sSelectors instanceof HTMLElement;
 oQuery.nodes = isElement ? [].concat(sSelectors) : document.querySelectorAll(sSelectors);
 oQuery.cssNodes = Array.prototype.map.call(oQuery.nodes, function (oInlineCSS) {
 return oInlineCSS.style;
 });
 oQuery.attr = setAttribs;
 oQuery.css = setStyles;
 oQuery.next = findNext;
 oQuery.parent = findMom;
 oQuery.follow = getNodes;
 oQuery.toString = getSelectors;
 oQuery.valueOf = getNodes;
 return oQuery;
 });
 })();
 */


var dg = (function () {
    return function (event) {
        return function (e) {
            var bindedTarget = e.currentTarget;
            var arr = dg.moms.get(bindedTarget).get(event);
            for (let singular of arr) {
                var element = e.target;
                do {
                    if (!dg.fn_filter(element, singular.child.uid)) continue;
                    singular.callback.apply(element, [element].concat([e, singular.child.oppressId]));
                } while (element != bindedTarget && (element = element.parentNode));
            }
        };
    };
})();


dg.moms = new Map();
dg.momsBusy = new Map();

dg.fn_filter = function (element, filter) {
    var arrFilter = filter.split(' ');
    var i = 0,
        len = arrFilter.length;
    for (; i < len; i++) {
        var tmpObj = {};
        if ('#' === arrFilter[i][0]) {
            tmpObj.ID = arrFilter[i].slice(1);
        } else if ('.' === arrFilter[i][0]) {
            tmpObj.className = arrFilter[i].slice(1);
        } else {
            tmpObj.tagName = arrFilter[i];
        }
        var index = undefined;
        for (index in tmpObj) {
            if (tmpObj.hasOwnProperty(index)) {
                if (!new RegExp('(\\s|^)' + tmpObj[index] + '($|\\s)', "i").test(element[index])) return false;
            }
        }
    }
    return true;
};
var addEvent = function (event, mom, child, callback) {
    if (!dg.moms.has(mom)) {
        dg.moms.set(mom, new Map());
    }
    let momMap = dg.moms.get(mom);
    if (!momMap.has(event)) {
        mom.addEventListener(event, dg(event));
        momMap.set(event, [{child, callback}]);
    } else {
        var events = momMap.get(event);
        events.push({child, callback});
        events = events.sort(function (a, b) {
            return $(a.child.uid).contains($(b.child.uid));
        });
        momMap.set(event, events);
    }
}

var delegate = (function delegate() {

    var events2 = {
        onclick: ['click'],
        ontouchstart: ['touchstart'],
        ontouchmove: ['touchmove'],
        ontouchend: ['touchend'],
        onanimationend: ['animationend', 'webkitAnimationEnd']

    }

    let mom = document.getElementsByTagName('body')[0];

    return function (child) {
        if (!Array.isArray(child)) {
            child = [child];
        }
        var i = 0, len = child.length;
        for (; i < len; i++) {
            for (var index in events2) {
                if (events2.hasOwnProperty(index)) {
                    if (index in child[i]) {
                        let value = events2[index];
                        for (var j = 0; j < value.length; j++) {
                            addEvent(value[j], $(child[i].momId), child[i], child[i][index])
                        }
                    }
                }
            }
        }
    }
})();
/*var dg = (function () {
 return function (child, callback) {
 return function (e) {
 var j = 0;
 var element = e.target;
 var bindedTarget = e.currentTarget;
 do {
 if (!dg.fn_filter(element, child.uid)) continue;
 callback.apply(element, [].concat.apply([element], [e, child.oppressId]));
 } while (element != bindedTarget && (element = element.parentNode));
 };
 };
 })();
 dg.moms = new Map();
 dg.momsBusy = new Map();

 dg.fn_filter = function (element, filter) {
 var arrFilter = filter.split(' ');
 var i = 0,
 len = arrFilter.length;
 for (; i < len; i++) {
 var tmpObj = {};
 if ('#' === arrFilter[i][0]) {
 tmpObj.ID = arrFilter[i].slice(1);
 } else if ('.' === arrFilter[i][0]) {
 tmpObj.className = arrFilter[i].slice(1);
 } else {
 tmpObj.tagName = arrFilter[i];
 }
 var index = undefined;
 for (index in tmpObj) {
 if (tmpObj.hasOwnProperty(index)) {
 if (!new RegExp('(\\s|^)' + tmpObj[index] + '($|\\s)', "i").test(element[index])) return false;
 }
 }
 }
 return true;
 };
 var addEvent = function (event, mom, child, callback) {
 if (!dg.moms.has(mom)) {
 dg.moms.set(mom, new Map());
 }
 var momMap=dg.moms.get(mom);
 if(!momMap.has(event)){
 mom.addEventListener(event,dg);
 momMap.set(event,[{child,callback}]);
 }else{
 momMap.get(event).push({child,callback});
 }
 }


 var delegate = (function delegate() {

 return function (mom, child) {
 if (child.momId) {
 mom = document.querySelector(child.momId);
 }
 if (Array.isArray(child)) {
 var i = 0, len = child.length;
 for (; i < len; i++) {
 if (child[i].onclick) mom.addEventListener('click', dg(child[i], child[i].onclick));
 if (child[i].ontouchstart) mom.addEventListener('touchstart', dg(child[i], child[i].ontouchstart));
 if (child[i].ontouchmove) mom.addEventListener('touchmove', dg(child[i], child[i].ontouchmove));
 if (child[i].ontouchend) mom.addEventListener('touchend', dg(child[i], child[i].ontouchend));
 if (child[i].onanimationend) {
 mom.addEventListener('animationend', dg(child[i], child[i].onanimationend));
 mom.addEventListener('webkitAnimationEnd', dg(child[i], child[i].onanimationend));
 }
 }
 } else if ("object" === typeof(child)) {
 if (child.onclick) mom.addEventListener('click', dg(child, child.onclick));
 if (child.ontouchstart) mom.addEventListener('touchstart', dg(child, child.ontouchstart));
 if (child.ontouchmove) mom.addEventListener('touchmove', dg(child, child.ontouchmove));
 if (child.ontouchend) mom.addEventListener('touchend', dg(child, child.ontouchend));
 if (child.onanimationend) {
 mom.addEventListener('animationend', dg(child, child.onanimationend));
 mom.addEventListener('webkitAnimationEnd', dg(child, child.onanimationend));
 }
 }
 }
 })();*/
var first2Low = function (str) {
    if ("string" != typeof str || str.length < 1) {
        console.error('wrong format no a string');
        return;
    }
    return str.replace(/./, str.charAt(0).toLowerCase());
}

var getScript = function () {

    var scriptSrc, callback;
    for (let i = 0; i < arguments.length; i++) {
        if (/js$/.test(arguments[i])) {
            scriptSrc = arguments[i];
        } else if ("function" == typeof arguments[i]) {
            callback = arguments[i];
        }
    }
    var existScripts = [].slice.call(document.getElementsByTagName('script')).map(function (value) {
        return value.getAttribute('src');
    });
    if (existScripts.indexOf(scriptSrc) > -1) {
        if ("function" == typeof callback) {
            callback();
            return;
        }
    }
    var script = document.createElement('script');
    var body = document.getElementsByTagName('body')[0];
    script.onload = function () {
        if ("function" == typeof callback) {
            callback();
        } else {
            throw new Error('no callback in getScript');
        }
    };
    script.onerror = function (e) {
        console.warn('No corresponding ' + script.getAttribute('src') + ' exists');
        body.removeChild(script);
    }
    script.src = scriptSrc;
    body.appendChild(script);
}
var ajax = function (method) {
    method = method ? method : 'get';
    return function (url, callback, form, timeout, outback) {
        if (!navigator.onLine) {
            return;
        }
        if (form instanceof FormData)
            form.append('LS', +new Date());
        var data = form ? form : null;
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open(method, url);

        if (timeout && outback) {
            xmlhttp.timeout = timeout;
            xmlhttp.ontimeout = function () {
                outback();
            }
        }
        xmlhttp.onreadystatechange = function () {
            if ((4 == xmlhttp.readyState) && (200 == xmlhttp.status)) {
                if ("function" == typeof(callback))
                    (callback(xmlhttp.responseText)) && (xmlhttp = null);
            }
        };
        xmlhttp.send(data);
        return xmlhttp;
    }
};

var str2class = function (str) {
    return '.' + str;
}
var getIndex = function (parasitifer) {
    return [].indexOf.call(parasitifer.parentNode.children, parasitifer);
}
var deviceDetect = function (device) {
    var mapList = {
        ios: /iPhone|iPad|iPod/,
        android: /Android/,
        weixin: /MicroMessenger/
    };
    return function () {
        return mapList[device].test(navigator.userAgent);
    }
};


module.exports = {
    $: $,
    $$: $$,
    gcs: gcs,
    delegate: delegate, /*
     domQuery: domQuery,*/
    getScript: getScript,
    first2Low: first2Low,
    get: ajax('get'),
    post: ajax('post'),
    str2class: str2class,
    getIndex: getIndex,
    isWX: deviceDetect('weixin'),
    isAndroid: deviceDetect('android'),
    isIOS: deviceDetect('ios')
};